import hashlib
import time
from sanic import Blueprint, Request, Sanic, json as jsonResp
import json
from sqlalchemy import Select
from sqlalchemy.orm import Session
from app.core.entity import ApiResult
from app.core.exception import ApiException
from app.entity.user import User
from app import myApp
from app.service.projectUser import ProjectUserService
from app.service.user import UserService
from jsonschema import validate

from app.utils.RequestUtils import RequestUtils
from app.utils.FileUtils import FileUtils

bp=Blueprint("user",url_prefix="/user")



@bp.route('/index',methods=['GET'])
async def test(request):
    user=User(username="admin",password="123456",nickname="管理员")
    myApp.redis.hset("user",'data', json.dumps(user.toDic()) )
    return jsonResp(user.toDic())

@bp.route('/create',methods=['GET'])
async def createUser(request):
    user=User(username="admin",password="123456",nickname="管理员")
    user.save()
    user.commit()
    return jsonResp(user.toDic())

registerSchema={
    "type":"object",
    "properties":{
        "phone":{"type":"string"},
        "password":{"type":"string"},
        "captchaKey":{"type":"string"},
        "captchaVal":{"type":"string"},
    },
    "required":["phone","password","captchaKey","captchaVal"]
}

@bp.route('/register',methods=['post'])
async def registerUser(request:Request):
    data=request.load_json()
    if(data==None): 
        data={}
    validate(instance=data,schema=registerSchema)
    UserService.register(data)
    return jsonResp(vars(ApiResult.success()))

@bp.route('/update/<id:int>/<username:str>',methods=['GET'])
async def updateUser(request,id,username):
    user=User.get(id)
    if(user==None):
        raise ApiException("无此用户")
    user.nickname=username
    user.save()
    user.commit()
    return jsonResp(user.toDic())

@bp.route("/login",methods=["POST"])
async def loginUser(request:Request):
    postData=request.load_json()
    token,user,exprire=UserService.login(postData['username'],postData['password'],postData['loginType'],
                                 postData['captchaKey'],postData['captchaValue'])
    userJson=user.toJson()
    userJson['exprire']=exprire
    return jsonResp(vars(ApiResult.success(data={"token":token,"user":userJson})))

@bp.route("/logout",methods=["POST"])
async def logoutUser(request:Request):
    token=request.headers.get("x-token")
    UserService.logout(token)
    return jsonResp(vars(ApiResult.success()))

@bp.route("/upload/avatar",methods=["POST"])
async def uploadAvatar(request:Request):
    file=request.files.get("file")
    token=request.headers.get("x-token")
    user=UserService.getUserByToken(token=token)
    fileMd5Name=(str(user.id)+"_"+str(time.time())).encode("utf-8")
    fileMd5Name = hashlib.md5(fileMd5Name).hexdigest()
    filename="/user/"+str(user.id)+"/"+fileMd5Name+"."+FileUtils.getExtention(file.name)
    fileUtils=FileUtils()
    fileUtils.setDiskConfig("avatar")
    url=fileUtils.upload(file,filename)
    host=request.scheme+"://"+request.host
    user.avatarUrl=host+url
    user.save()
    user=UserService.getUserByToken(token=token)
    return jsonResp(vars(ApiResult.success(data={"url":user.avatarUrl})))

@bp.route("/myinfo/upd/<field>",methods=["POST"])
async def myInfoUpd(request:Request,field):
    token=request.headers.get("x-token")
    postData=request.load_json()
    user=UserService.getUserByToken(token=token)
    UserService.chkInfoUpdValue(field,postData["value"],user.id)
    user.__setattr__(field,postData["value"])
    user.save()
    return jsonResp(vars(ApiResult.success()))

@bp.route("/chkLogin",methods=["GET"])
async def chkLogin(request:Request,field):
    UserService().checkLogin(RequestUtils().getToken())
    return jsonResp(vars(ApiResult.success()))

@bp.route("/search",methods=["POST"])
async def search(request:Request):
    postData=request.load_json()
    if postData==None:
        postData={}
    users=UserService.searchUser(postData['keyword'])
    projectId=RequestUtils().getCurrentProjectId()
    respList=[]
    for user in users:
        obj={
            "id":user.id,
            "username":user.username,
            "nickname":user.nickname,
            "avatarUrl":user.avatarUrl,
            "invited":"Y" if ProjectUserService.inProject(projectId,user.id)>0 else "N"
        }
        respList.append(obj)
    return jsonResp(vars(ApiResult.success(data={"list":respList})))